#include "graphe.hpp"
#include "liste.hpp"

void initGraphe(graphe &g, bool verbose) {
    g.noeuds = NULL;
    g.nb_noeuds = 0;
    g.capa_noeuds = 0;

    g.arcs = NULL;
    g.nb_arcs = 0;
    g.capa_arcs = 0;
}

int ajoutArc(graphe &g, const string &src, const string &dst, int val, bool verbose) {

    int pos_src = chercherNoeud(g, src);
    int pos_dst = chercherNoeud(g, dst);

    if(pos_src >= 0 && pos_dst >= 0)
    {
        int pos = chercherArc(g, src, dst);
        if(pos >= 0)
        {
            g.arcs[pos]->valeur = val;
            return pos;
        }
        else
        {
            Arc a;
            initArc(a, *(g.noeuds[pos_src]), *(g.noeuds[pos_dst]), val, verbose);
            if(g.nb_arcs == g.capa_arcs)
            {
                if(g.capa_arcs == 0)
                {
                    g.capa_arcs = 1;
                    g.arcs = (Arc**) malloc(sizeof(Arc*)*g.capa_arcs);
                } else {
                    g.capa_arcs *= 2;
                    g.arcs = (Arc**) realloc(g.arcs, sizeof(Arc*)*g.capa_arcs);
                }
            }
            g.arcs[g.nb_arcs] = &a;
            g.nb_arcs ++;
        }
        return g.nb_arcs -1;
    }
    else
    {
        if (pos_src < 0)
            cout << "le noeud " << src << " n'existe pas" << endl;
        if (pos_dst < 0)
            cout << "le noeud " << dst << " n'existe pas" << endl;
        return -1;
    }
}

void ajoutNoeud(graphe &g, Noeud* n, bool verbose) {
     if (chercherNoeud(g, n->nom, verbose) < 0)
    {
        if (verbose)
            cout << "ajout du noeud" << endl;


        if (verbose)
            cout << "noeud initialisé" << endl;

        if(g.nb_noeuds == g.capa_noeuds)
        {
            if (verbose)
                cout << "agrandissement de la taille du tableau de noeuds" << endl;
            if (g.capa_noeuds == 0)
            {
                g.capa_noeuds = 1;
                g.noeuds = (Noeud **) malloc(sizeof(Noeud*));
            } else {
                g.capa_noeuds *= 2;
                g.noeuds = (Noeud **) realloc(g.noeuds, sizeof(Noeud*)*g.capa_noeuds);
            }
        }
        g.noeuds[g.nb_noeuds] = n;
        g.nb_noeuds ++;

        if(verbose)
            cout << "nb_noeuds " << g.nb_noeuds << " / capa_noeuds " << g.capa_noeuds << endl;

        if (verbose) {
                    cout << "fin d'ajout du noeud" << endl << endl;
                    cout << "\taffichage du tableau de noeuds actuel" << endl;
                    for(int i = 0; i < g.nb_noeuds; i++)
                        cout << i << " : " << g.noeuds[i]->nom << endl;

                    cout << endl;
        }
    }
    else
    {
        cout << "il existe déjà un noeud " << n->nom << endl << endl;
        if(verbose)
            cout << "nb_noeuds " << g.nb_noeuds << " / capa_noeuds " << g.capa_noeuds << endl;

        if(verbose) {
        cout << "\taffichage du tableau de noeuds actuel" << endl;
                    for(int i = 0; i < g.nb_noeuds; i++)
                        cout << i << " : " << g.noeuds[i]->nom << endl;

                    cout << endl;
        }
    }
}

void ajoutNoeud(graphe &g, const string & nomNoeud, bool verbose) {
        if (verbose)
            cout << "ajout du noeud" << endl;

        Noeud n;
        initNoeud(n, nomNoeud, verbose);

        ajoutNoeud(g, &n, verbose);
}

void afficherGraphe(const graphe &g, bool verbose) {
    if (verbose) {
        cout << "affichage du graphe" << endl;
    }

    if (verbose)
        cout << "\taffichage des noeuds" << endl;

    for(int i = 0; i < g.nb_noeuds; i++ ) {
        afficherNoeud(*(g.noeuds[i]));
    }

    //affichageListe(g.noeuds);
    // affichageListe(g.arcs);
}

void testamentGraphe(graphe &g, bool verbose) {
// a finir
/*
    for(int i = 0; i<g.nb_noeuds; i++)
    {
        testamentNoeud(*(g.noeuds[i]));
    }
    g.nb_noeuds = 0; */
    //testamentListe(g.noeuds, verbose);
   // testamentListe(g.arcs, verbose);
}

int chercherNoeud (const graphe &g, const string & nomNoeud, bool verbose)
{

    if(verbose) {
        cout << "dans recherche de " << nomNoeud << endl;
        cout << "nb_noeuds : " << g.nb_noeuds << " / capa_noeuds : " << g.capa_noeuds << endl;
    }

    for(int i = 0; i<g.nb_noeuds; i++)
    {

        if(verbose) {
            cout << i << " : " << g.noeuds[i]->nom << endl;
        }

        if (nomNoeud.compare(valeurNoeud(*(g.noeuds[i]))) == 0)
        {
            return i;
        }
    }
    return -1;
}

int chercherArc (const graphe &g, const string & source, const string & destination, bool verbose)
{
    for(int i = 0; i<g.nb_arcs; i++)
    {
        if((source.compare(sourceArc(*(g.arcs[i]))) == 0) && (destination.compare(destinationArc(*(g.arcs[i]))) == 0))
        {
            return i;
        }
    }
    return -1;
}
